﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO.Ports;
using IPC.Communication.Framework.BasicFramework;
using IPC.Communication.Framework.Reflection;
using IPC.Communication.Framework.Serial;

namespace IPC.Communication.Framework.Profinet.IDCard
{
    public class SAMSerial : SerialBase
    {
        protected override OperateResult<byte[]> SPReceived(SerialPort serialPort, bool awaitData)
        {
            List<byte> list = new List<byte>();
            do
            {
                OperateResult<byte[]> operateResult = base.SPReceived(serialPort, awaitData);
                if (!operateResult.IsSuccess)
                {
                    return operateResult;
                }
                list.AddRange(operateResult.Content);
            }
            while (!CheckADSCommandCompletion(list));
            return OperateResult.CreateSuccessResult(list.ToArray());
        }

        [HslMqttApi]
        public OperateResult<string> ReadSafeModuleNumber()
        {
            byte[] send = PackToSAMCommand(BuildReadCommand(18, byte.MaxValue, null));
            OperateResult<byte[]> operateResult = ReadFromCoreServer(send);
            if (!operateResult.IsSuccess)
            {
                return OperateResult.CreateFailedResult<string>(operateResult);
            }
            OperateResult operateResult2 = CheckADSCommandAndSum(operateResult.Content);
            if (!operateResult2.IsSuccess)
            {
                return OperateResult.CreateFailedResult<string>(operateResult2);
            }
            return ExtractSafeModuleNumber(operateResult.Content);
        }

        [HslMqttApi]
        public OperateResult CheckSafeModuleStatus()
        {
            byte[] send = PackToSAMCommand(BuildReadCommand(18, byte.MaxValue, null));
            OperateResult<byte[]> operateResult = ReadFromCoreServer(send);
            if (!operateResult.IsSuccess)
            {
                return OperateResult.CreateFailedResult<string>(operateResult);
            }
            OperateResult operateResult2 = CheckADSCommandAndSum(operateResult.Content);
            if (!operateResult2.IsSuccess)
            {
                return OperateResult.CreateFailedResult<string>(operateResult2);
            }
            if (operateResult.Content[9] != 144)
            {
                return new OperateResult(GetErrorDescription(operateResult.Content[9]));
            }
            return OperateResult.CreateSuccessResult();
        }

        [HslMqttApi]
        public OperateResult SearchCard()
        {
            byte[] send = PackToSAMCommand(BuildReadCommand(32, 1, null));
            OperateResult<byte[]> operateResult = ReadFromCoreServer(send);
            if (!operateResult.IsSuccess)
            {
                return OperateResult.CreateFailedResult<string>(operateResult);
            }
            OperateResult operateResult2 = CheckADSCommandAndSum(operateResult.Content);
            if (!operateResult2.IsSuccess)
            {
                return OperateResult.CreateFailedResult<string>(operateResult2);
            }
            if (operateResult.Content[9] != 159)
            {
                return new OperateResult(GetErrorDescription(operateResult.Content[9]));
            }
            return OperateResult.CreateSuccessResult();
        }

        [HslMqttApi]
        public OperateResult SelectCard()
        {
            byte[] send = PackToSAMCommand(BuildReadCommand(32, 2, null));
            OperateResult<byte[]> operateResult = ReadFromCoreServer(send);
            if (!operateResult.IsSuccess)
            {
                return OperateResult.CreateFailedResult<string>(operateResult);
            }
            OperateResult operateResult2 = CheckADSCommandAndSum(operateResult.Content);
            if (!operateResult2.IsSuccess)
            {
                return OperateResult.CreateFailedResult<string>(operateResult2);
            }
            if (operateResult.Content[9] != 144)
            {
                return new OperateResult(GetErrorDescription(operateResult.Content[9]));
            }
            return OperateResult.CreateSuccessResult();
        }

        [HslMqttApi]
        public OperateResult<IdentityCard> ReadCard()
        {
            byte[] send = PackToSAMCommand(BuildReadCommand(48, 1, null));
            OperateResult<byte[]> operateResult = ReadFromCoreServer(send);
            if (!operateResult.IsSuccess)
            {
                return OperateResult.CreateFailedResult<IdentityCard>(operateResult);
            }
            OperateResult operateResult2 = CheckADSCommandAndSum(operateResult.Content);
            if (!operateResult2.IsSuccess)
            {
                return OperateResult.CreateFailedResult<IdentityCard>(operateResult2);
            }
            return ExtractIdentityCard(operateResult.Content);
        }

        public override string ToString()
        {
            return String.Format("SAMSerial[{0}:{1}]", base.PortName, base.BaudRate);
        }

        public static byte[] PackToSAMCommand(byte[] command)
        {
            byte[] array = new byte[command.Length + 8];
            array[0] = 170;
            array[1] = 170;
            array[2] = 170;
            array[3] = 150;
            array[4] = 105;
            array[5] = BitConverter.GetBytes(array.Length - 7)[1];
            array[6] = BitConverter.GetBytes(array.Length - 7)[0];
            command.CopyTo(array, 7);
            int num = 0;
            for (int i = 5; i < array.Length - 1; i++)
            {
                num ^= array[i];
            }
            array[array.Length - 1] = (byte)num;
            return array;
        }

        public static byte[] BuildReadCommand(byte cmd, byte para, byte[] data)
        {
            if (data == null)
            {
                data = new byte[0];
            }
            byte[] array = new byte[2 + data.Length];
            array[0] = cmd;
            array[1] = para;
            data.CopyTo(array, 2);
            return array;
        }

        public static bool CheckADSCommandCompletion(List<byte> input)
        {
            if (input != null && input.Count < 8)
            {
                return false;
            }
            if (input[5] * 256 + input[6] > input.Count - 7)
            {
                return false;
            }
            return true;
        }

        public static OperateResult CheckADSCommandAndSum(byte[] input)
        {
            if (input != null && input.Length < 8)
            {
                return new OperateResult(StringResources.Language.SAMReceiveLengthMustLargerThan8);
            }
            if (input[0] != 170 || input[1] != 170 || input[2] != 170 || input[3] != 150 || input[4] != 105)
            {
                return new OperateResult(StringResources.Language.SAMHeadCheckFailed);
            }
            if (input[5] * 256 + input[6] != input.Length - 7)
            {
                return new OperateResult(StringResources.Language.SAMLengthCheckFailed);
            }
            int num = 0;
            for (int i = 5; i < input.Length - 1; i++)
            {
                num ^= input[i];
            }
            if (num != input[input.Length - 1])
            {
                return new OperateResult(StringResources.Language.SAMSumCheckFailed);
            }
            return OperateResult.CreateSuccessResult();
        }

        public static OperateResult<string> ExtractSafeModuleNumber(byte[] data)
        {
            try
            {
                if (data[9] != 144)
                {
                    return new OperateResult<string>(GetErrorDescription(data[9]));
                }
                StringBuilder stringBuilder = new StringBuilder();
                stringBuilder.Append(data[10].ToString("D2"));
                stringBuilder.Append(".");
                stringBuilder.Append(data[12].ToString("D2"));
                stringBuilder.Append("-");
                stringBuilder.Append(BitConverter.ToInt32(data, 14).ToString());
                stringBuilder.Append("-");
                stringBuilder.Append(BitConverter.ToInt32(data, 18).ToString("D9"));
                stringBuilder.Append("-");
                stringBuilder.Append(BitConverter.ToInt32(data, 22).ToString("D9"));
                return OperateResult.CreateSuccessResult(stringBuilder.ToString());
            }
            catch (Exception ex)
            {
                return new OperateResult<string>("Error:" + ex.Message + "  Source Data: " + SoftBasic.ByteToHexString(data));
            }
        }

        public static OperateResult<IdentityCard> ExtractIdentityCard(byte[] data)
        {
            try
            {
                if (data[9] != 144)
                {
                    return new OperateResult<IdentityCard>(GetErrorDescription(data[9]));
                }
                string @string = Encoding.Unicode.GetString(data, 14, 256);
                byte[] portrait = SoftBasic.ArraySelectMiddle(data, 270, 1024);
                IdentityCard identityCard = new IdentityCard();
                identityCard.Name = @string.Substring(0, 15);
                identityCard.Sex = ((@string.Substring(15, 1) == "1") ? "男" : ((@string.Substring(15, 1) == "2") ? "女" : "未知"));
                identityCard.Nation = GetNationText(Convert.ToInt32(@string.Substring(16, 2)));
                identityCard.Birthday = new DateTime(int.Parse(@string.Substring(18, 4)), int.Parse(@string.Substring(22, 2)), int.Parse(@string.Substring(24, 2)));
                identityCard.Address = @string.Substring(26, 35);
                identityCard.Id = @string.Substring(61, 18);
                identityCard.Organ = @string.Substring(79, 15);
                identityCard.ValidityStartDate = new DateTime(int.Parse(@string.Substring(94, 4)), int.Parse(@string.Substring(98, 2)), int.Parse(@string.Substring(100, 2)));
                identityCard.ValidityEndDate = new DateTime(int.Parse(@string.Substring(102, 4)), int.Parse(@string.Substring(106, 2)), int.Parse(@string.Substring(108, 2)));
                identityCard.Portrait = portrait;
                return OperateResult.CreateSuccessResult(identityCard);
            }
            catch (Exception ex)
            {
                return new OperateResult<IdentityCard>(ex.Message);
            }
        }

        public static string GetNationText(int nation)
        {
            switch (nation)
            {
                case 1:
                    return "汉";
                case 2:
                    return "蒙古";
                case 3:
                    return "回";
                case 4:
                    return "藏";
                case 5:
                    return "维吾尔";
                case 6:
                    return "苗";
                case 7:
                    return "彝";
                case 8:
                    return "壮";
                case 9:
                    return "布依";
                case 10:
                    return "朝鲜";
                case 11:
                    return "满";
                case 12:
                    return "侗";
                case 13:
                    return "瑶";
                case 14:
                    return "白";
                case 15:
                    return "土家";
                case 16:
                    return "哈尼";
                case 17:
                    return "哈萨克";
                case 18:
                    return "傣";
                case 19:
                    return "黎";
                case 20:
                    return "傈僳";
                case 21:
                    return "佤";
                case 22:
                    return "畲";
                case 23:
                    return "高山";
                case 24:
                    return "拉祜";
                case 25:
                    return "水";
                case 26:
                    return "东乡";
                case 27:
                    return "纳西";
                case 28:
                    return "景颇";
                case 29:
                    return "柯尔克孜";
                case 30:
                    return "土";
                case 31:
                    return "达斡尔";
                case 32:
                    return "仫佬";
                case 33:
                    return "羌";
                case 34:
                    return "布朗";
                case 35:
                    return "撒拉";
                case 36:
                    return "毛南";
                case 37:
                    return "仡佬";
                case 38:
                    return "锡伯";
                case 39:
                    return "阿昌";
                case 40:
                    return "普米";
                case 41:
                    return "塔吉克";
                case 42:
                    return "怒";
                case 43:
                    return "乌孜别克";
                case 44:
                    return "俄罗斯";
                case 45:
                    return "鄂温克";
                case 46:
                    return "德昂";
                case 47:
                    return "保安";
                case 48:
                    return "裕固";
                case 49:
                    return "京";
                case 50:
                    return "塔塔尔";
                case 51:
                    return "独龙";
                case 52:
                    return "鄂伦春";
                case 53:
                    return "赫哲";
                case 54:
                    return "门巴";
                case 55:
                    return "珞巴";
                case 56:
                    return "基诺";
                case 97:
                    return "其他";
                case 98:
                    return "外国血统中国籍人士";
                default:
                    return string.Empty;
            }
        }

        public static IEnumerator<string> GetNationEnumerator()
        {
            for (int i = 1; i < 57; i++)
            {
                yield return GetNationText(i);
            }
        }

        public static string GetErrorDescription(int err)
        {
            switch (err)
            {
                case 145:
                    return StringResources.Language.SAMStatus91;
                case 16:
                    return StringResources.Language.SAMStatus10;
                case 17:
                    return StringResources.Language.SAMStatus11;
                case 33:
                    return StringResources.Language.SAMStatus21;
                case 35:
                    return StringResources.Language.SAMStatus23;
                case 36:
                    return StringResources.Language.SAMStatus24;
                case 49:
                    return StringResources.Language.SAMStatus31;
                case 50:
                    return StringResources.Language.SAMStatus32;
                case 51:
                    return StringResources.Language.SAMStatus33;
                case 64:
                    return StringResources.Language.SAMStatus40;
                case 65:
                    return StringResources.Language.SAMStatus41;
                case 71:
                    return StringResources.Language.SAMStatus47;
                case 96:
                    return StringResources.Language.SAMStatus60;
                case 102:
                    return StringResources.Language.SAMStatus66;
                case 128:
                    return StringResources.Language.SAMStatus80;
                case 129:
                    return StringResources.Language.SAMStatus81;
                default:
                    return StringResources.Language.UnknownError;
            }
        }
    }
}